const MongoDB = require('./mongodb')

class Controller {
    constructor(database, dbname) {
        this.collection = database
        this.dbname = dbname
        this.command = new MongoDB(database)
        this.validKeys = Object.keys(database.prototype.schema.obj)
    }

    async insertOne(req, res) {
        if (!this) {
            res.send({ code: 500, msg: '提示：网络接口的控制层的调用者是undefined,请使用bind来改变函数的调用者' })
            return
        }
        try {
            const record = new this.collection(req.body || req.query)
            const result = {
                code: 200,
                msg: '在' + this.dbname + '中插入一条数据'
            }
            await record.save()
            result.record = req.body || req.query
            res.send(JSON.stringify(result))
        } catch (err) {
            res.send({ code: 500, msg: '传入参数不合法' })
        }

    }

    async insertMany(req, res) {
        if (!this) {
            res.send({ code: 500, msg: '提示：网络接口的控制层的调用者是undefined,请使用bind来改变函数的调用者' })
            return
        }
        try {
            const data = this.collection.insertMany(req.body || req.query)
            const result = {
                code: 200,
                msg: '在' + this.dbname + '中批量插入数据'
            }
            result.record = req.body || req.query
            res.send(JSON.stringify(result))
        } catch (error) {
            res.json({ code: 500, msg: '部分参数不合法' })
        }
    }

    async getOne(req, res) {
        if (!this) {
            res.send({ code: 500, msg: '提示：网络接口的控制层的调用者是undefined,请使用bind来改变函数的调用者' })
            return
        }
        const data = await this.collection.findOne(req.query)
        const result = {
            code: 200,
            msg: '获取' + this.dbname + '一条记录',
            data
        }
        res.send(JSON.stringify(result))
    }

    async getAll(req, res) {
        if (!this) {
            res.send({ code: 500, msg: '提示：网络接口的控制层的调用者是undefined,请使用bind来改变函数的调用者' })
            return
        }
        const data = await this.collection.find(req.query)
        const result = {
            code: 200,
            msg: '获取全部' + this.dbname + '列表',
            count: data.length,
            data
        }
        res.send(JSON.stringify(result))
    }

    async getPage(req, res) {
        if (!this) {
            res.send({ code: 500, msg: '提示：网络接口的控制层的调用者是undefined,请使用bind来改变函数的调用者' })
            return
        }
        const { pageNum, pageLength, ...query } = req.query
        const data = await this.collection.find(query).skip((pageNum - 1) * pageLength).limit(pageLength)
        const result = {
            code: 200,
            msg: '分页获取' + this.dbname + '列表',
            data
        }
        res.send(JSON.stringify(result))
    }

    async updateOne(req, res) {
        if (!this) {
            res.send({ code: 500, msg: '提示：网络接口的控制层的调用者是undefined,请使用bind来改变函数的调用者' })
            return
        }
        const isValid = Object.keys(req.body).every(key => this.validKeys.includes(key))
        const data = isValid ? await this.collection.updateOne(req.query, req.body) : []
        const result = {
            code: 200,
            msg: '更新' + this.dbname,
            detail: ''
        }
        if (data?.modifiedCount) {
            result.detail = '修改信息成功'
        } else {
            isValid ? result.code = 200 : result.code = 500
            isValid ? result.detail = '信息保持不变' : result.detail = '传入参数不合法'
        }
        res.send(JSON.stringify(result))
    }

    async updateMany(req, res) {
        if (!this) {
            res.send({ code: 500, msg: '提示：网络接口的控制层的调用者是undefined,请使用bind来改变函数的调用者' })
            return
        }
        const isValid = Object.keys(req.body).every(key => this.validKeys.includes(key))
        const data = isValid ? await this.collection.updateMany(req.query, req.body) : []
        const result = {
            code: 200,
            msg: '更新' + this.dbname + '全部数据',
            detail: ''
        }
        if (data?.modifiedCount) {
            result.detail = '修改信息成功，更新了' + data.modifiedCount + '条数据'
        } else {
            isValid ? result.code = 200 : result.code = 500
            isValid ? result.detail = '信息保持不变' : result.detail = '参数不合法'
        }
        res.send(JSON.stringify(result))
    }

    async deleteOne(req, res) {
        if (!this) {
            res.send({ code: 500, msg: '提示：网络接口的控制层的调用者是undefined,请使用bind来改变函数的调用者' })
            return
        }
        const isValid = Object.keys(req.body).every(key => this.validKeys.includes(key))
        const data = isValid ? await this.collection.deleteOne(req.body) : []
        const result = {
            code: 200,
            msg: '删除' + this.dbname + '中的数据',
            detail: ''
        }
        if (data?.deletedCount) {
            result.detail = '删除' + data.deletedCount + '条数据'
        } else {
            isValid ? result.code = 404 : result.code = 500
            isValid ? result.detail = '没有找到可删除的数据' : result.detail = '参数不合法，请检查'
        }
        res.send(JSON.stringify(result))
    }

    async deleteMany(req, res) {
        if (!this) {
            res.send({ code: 500, msg: '提示：网络接口的控制层的调用者是undefined,请使用bind来改变函数的调用者' })
            return
        }
        const isValid = Object.keys(req.body).every(key => this.validKeys.includes(key))
        const data = isValid ? await this.collection.deleteMany(req.body) : []
        const result = {
            code: 200,
            msg: '批量删除' + this.dbname + '中的数据'
        }
        if (data.deletedCount) {
            result.detail = '删除' + data.deletedCount + '条数据'
        } else {
            isValid ? result.code = 404 : result.code = 500
            isValid ? result.detail = '没有找到可删除的数据' : result.detail = '参数不合法，请检查'
        }
        res.send(JSON.stringify(result))
    }
}

module.exports = Controller
